package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.sql.Timestamp;

import javax.swing.JDialog;

import org.apache.commons.beanutils.BeanUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import util.HibernateUtil;
import view.EditBookPage;
import bean.Book;
import bean.Catalog;

import com.mysql.jdbc.StringUtils;

import dto.BookDTO;
import dto.LogonDTO;

public class EditBookController {

	private EditBookPage editBook;
	private CommonBookController commonController;
	private BookDTO dto;
	private String userName;
	private String errorMessage;

	void editBook(LogonDTO logonDTO, BookDTO bookDTO) {
		commonController = new CommonBookController();
		userName = logonDTO.getUserName();

		editBook = new EditBookPage(logonDTO, bookDTO);

		editBook.addEditBookButtonListener(new EditBookListener());
		editBook.addGetISBNInfoButtonListener(commonController.new GetISBNInfoListener(
				editBook));

		editBook.setModal(true);
		editBook.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		editBook.setVisible(true);
	}

	class EditBookListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {
			dto = editBook.getBookDTO();

			if (validateBookEntry()) {
				editBookInDB();
				editBook.displayMessage("\"" + dto.getTitle()
						+ "\" has been updated.");
			} else {
				editBook.displayMessage(errorMessage);
			}
		}
	}

	private void editBookInDB() {

		commonController = new CommonBookController();

		Book bookBean = new Book();

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction transaction;

		Catalog catalogBean = commonController.fetchCatalogByDDC(dto
				.getDeweyDecimalNo());
		bookBean = catalogBean.getBook();

		try {
			// if ISBN is not edited
			if (dto.getISBN().equals(bookBean.getISBN())) {

				BeanUtils.copyProperties(bookBean, dto);
				bookBean.setEditedBy(userName);
				bookBean.setEditedDate(getCurrentTime());

				transaction = session.beginTransaction();
				session.saveOrUpdate(bookBean);
				transaction.commit();

			} else if (!dto.getISBN().equals(bookBean.getISBN())) {
				// if ISBN is edited

				Book newBook = commonController.fetchBookByISBN(dto.getISBN());

				if (newBook != null) {
					// if already existing in DB, update book and catalog

					BeanUtils.copyProperties(newBook, dto);
					newBook.setEditedBy(userName);
					newBook.setEditedDate(getCurrentTime());

					transaction = session.beginTransaction();
					session.saveOrUpdate(newBook);
					transaction.commit();

					catalogBean.setBook(newBook);
					catalogBean.setOnLoan("N");
					catalogBean.setEditedBy(userName);
					catalogBean.setEditedDate(getCurrentTime());

					transaction = session.beginTransaction();
					session.saveOrUpdate(catalogBean);
					transaction.commit();

				} else {
					// if not existing in DB, add book in DB, update catalog

					newBook = new Book();

					BeanUtils.copyProperties(newBook, dto);
					newBook.setEditedBy(userName);
					newBook.setEditedDate(getCurrentTime());

					transaction = session.beginTransaction();
					session.save(newBook);
					transaction.commit();

					catalogBean.setBook(newBook);
					catalogBean.setOnLoan("N");
					catalogBean.setEditedBy(userName);
					catalogBean.setEditedDate(getCurrentTime());

					transaction = session.beginTransaction();
					session.saveOrUpdate(catalogBean);
					transaction.commit();
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	private boolean validateBookEntry() {

		boolean isValid = true;

		if (StringUtils.isNullOrEmpty(dto.getTitle())) {
			errorMessage = "Title field should not be empty.";
			isValid = false;
		} else if (StringUtils.isNullOrEmpty(dto.getAuthor())) {
			errorMessage = "Author field should not be empty.";
			isValid = false;
		} else if (StringUtils.isNullOrEmpty(dto.getISBN())) {
			errorMessage = "ISBN field should not be empty.";
			isValid = false;
		} else if (StringUtils.isNullOrEmpty(dto.getDeweyDecimalNo())) {
			errorMessage = "Catalog field should not be empty.";
			isValid = false;
		}

		return isValid;
	}

	private Timestamp getCurrentTime() {
		java.util.Date date = new java.util.Date(System.currentTimeMillis());
		java.sql.Timestamp timestamp = new java.sql.Timestamp(date.getTime());

		return timestamp;
	}

}
